package co.gov.medellin.ssti.sub.model.dao.impl;

import java.math.BigDecimal;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.IncorrectResultSizeDataAccessException;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcDaoSupport;

import co.gov.medellin.ssti.sub.model.dao.BeneficioDAO;
import co.gov.medellin.ssti.sub.model.dao.exception.DAOException;
import co.gov.medellin.ssti.sub.model.service.AtributosService;
import co.gov.medellin.ssti.sub.model.service.SubprogramaService;
import co.gov.medellin.ssti.sub.model.vo.Beneficiario_AtributoVO;
import co.gov.medellin.ssti.sub.model.vo.BeneficioOtorgadoVO;
import co.gov.medellin.ssti.sub.model.vo.BeneficioVO;
import co.gov.medellin.ssti.sub.model.vo.SubprogramaSedeVO;
import co.gov.medellin.ssti.sub.model.vo.UsuarioxSedeVO;

public class BeneficioDAOImpl2 extends NamedParameterJdbcDaoSupport implements
		BeneficioDAO {
	@Autowired
	AtributosService atributosServiceImpl;
	@Autowired
	SubprogramaService subprogramaServiceImpl2;

	private static final String QUERY_EXISTE_BENEFICIARIO = "SELECT CODIGO FROM TCS_BEN_BENEFICIO_OTORGADO "
			+ " WHERE BEN_CODIGO = :BEN_CODIGO AND SBPR_CODIGO = :SBPR_CODIGO "
			+ " AND campo_a1 IS NULL";

	private static final String FIND_COSTO_BENEFICIO = "SELECT NVL(TRUNC(VALOR_UNITARIO_BENEFICIO),0) VALOR_UNITARIO_BENEFICIO FROM TCS_BEN_SUBPROGRAMA "
			+ " WHERE CODIGO = :CODIGO ";

	private static final String SELECT_VALOR_BY_CODEBOT = "SELECT VALOR FROM VCS_BENEFICIOS_OTORGADOS "
			+ " WHERE CODBOT = :CODBOT ";

	private static final String SELECT_FECHA_BOT_BY_CODEBOT = "SELECT TO_CHAR(TO_DATE(fecha, 'dd/mm/rrrr'), 'dd/mm/rrrr') fechaBOT "
			+ " FROM VCS_BENEFICIOS_OTORGADOS WHERE CODBOT = :CODBOT";

	private static final String SELECT_TERCERO_BOT_BY_CODEBOT = "SELECT trim(TERCERO) tercero "
			+ " FROM TCS_BEN_BENEFICIO_OTORGADO WHERE CODIGO = :CODIGO";

	private static final String SELECT_TIPO_BENEFICIO_BOT_BY_CODEBOT = "SELECT TRIM(TIPO_BENEFICIO) tipo "
			+ " FROM TCS_BEN_BENEFICIO_OTORGADO WHERE CODIGO = :CODIGO";

	private static final String SELECT_NUMERO_BEN_DISPONIBLE = "SELECT NUMERO_BEN_DISPONIBLE "
			+ " FROM TCS_BEN_SUBPROGRAMA_SEDE WHERE SEDE_CODIGO = :SEDE_CODIGO "
			+ " AND SBPR_CODIGO = :SBPR_CODIGO";

	public boolean isExisteBeneficiario(Long codeBeneficiario,
			Long codeSubprograma) {
		Map<String, Object> namedParameters = new HashMap<String, Object>();

		namedParameters.put("BEN_CODIGO", codeBeneficiario);
		namedParameters.put("SBPR_CODIGO", codeSubprograma);

		List<Map<String, Object>> ret = getNamedParameterJdbcTemplate()
				.queryForList(QUERY_EXISTE_BENEFICIARIO, namedParameters);
		System.out.println("query " + QUERY_EXISTE_BENEFICIARIO);
		System.out.println("ben_codigo " + codeBeneficiario);
		System.out.println("sbpr_codigo " + codeSubprograma);
		if (ret != null && ret.size() > 0) {
			return true;
		}
		return false;
	}

	public boolean isEmpresaBeneficiario(Long codeEmpresa, Long codeSubprograma) {
		Map<String, Object> namedParameters = new HashMap<String, Object>();
		String query = "SELECT CODIGO FROM TCS_BEN_BENEFICIO_OTORGADO "
				+ " WHERE CAMPO_N3 = :CAMPO_N3 AND SBPR_CODIGO = :SBPR_CODIGO "
				+ " AND campo_a1 IS NULL";

		namedParameters.put("CAMPO_N3", codeEmpresa);
		namedParameters.put("SBPR_CODIGO", codeSubprograma);
		List<Map<String, Object>> ret = getNamedParameterJdbcTemplate()
				.queryForList(query, namedParameters);
		System.out.println("query " + query);
		System.out.println("campo_n3 " + codeEmpresa);
		System.out.println("sbpr_codigo " + codeSubprograma);
		if (ret != null && ret.size() > 0) {
			return true;
		}
		return false;

	}

	public String findCostoBeneficio(Long codeBeneficio) {
		Map<String, Object> namedParameters = new HashMap<String, Object>();

		namedParameters.put("CODIGO", codeBeneficio);
		try {
			long valor = getNamedParameterJdbcTemplate().queryForObject(
					FIND_COSTO_BENEFICIO, namedParameters, Long.class);
			return String.valueOf(valor);
		} catch (IncorrectResultSizeDataAccessException e) {
			return String.valueOf(0);
		}
	}

	public String findCostoBOT(Long codeBot) {
		Map<String, Object> namedParameters = new HashMap<String, Object>();

		namedParameters.put("CODBOT", codeBot);
		Long valor = null;
		try {
			valor = getNamedParameterJdbcTemplate().queryForObject(
					SELECT_VALOR_BY_CODEBOT, namedParameters, Long.class);
			if (valor != null) {
				return String.valueOf(valor);
			}
		} catch (IncorrectResultSizeDataAccessException e) {
			// return String.valueOf(0);
		}
		return "";
	}

	public String findFechaBOT(Long codeBot) {
		Map<String, Object> namedParameters = new HashMap<String, Object>();

		namedParameters.put("CODBOT", codeBot.longValue());

		try {
			String fecha = getNamedParameterJdbcTemplate().queryForObject(
					SELECT_FECHA_BOT_BY_CODEBOT, namedParameters, String.class);
			return fecha;
		} catch (IncorrectResultSizeDataAccessException e) {
			return null;
		}
	}

	public String findTercero(Long codeBot) {
		Map<String, Object> namedParameters = new HashMap<String, Object>();

		namedParameters.put("CODIGO", codeBot);

		try {
			String tercero = getNamedParameterJdbcTemplate().queryForObject(
					SELECT_TERCERO_BOT_BY_CODEBOT, namedParameters,
					String.class);
			return tercero;
		} catch (IncorrectResultSizeDataAccessException e) {
			return null;
		}
	}

	public String findTipoBeneficio(Long codeBot) {
		Map<String, Object> namedParameters = new HashMap<String, Object>();

		namedParameters.put("CODIGO", codeBot);

		try {
			String tipo = getNamedParameterJdbcTemplate().queryForObject(
					SELECT_TIPO_BENEFICIO_BOT_BY_CODEBOT, namedParameters,
					String.class);
			return tipo;
		} catch (IncorrectResultSizeDataAccessException e) {
			return null;
		}
	}

	public int findDisponibilidad(Long codeSede, Long codeSubprograma) {
		Map<String, Object> namedParameters = new HashMap<String, Object>();

		namedParameters.put("SEDE_CODIGO", codeSede);
		namedParameters.put("SBPR_CODIGO", codeSubprograma);

		try {
			int disponibles = getNamedParameterJdbcTemplate().queryForObject(
					SELECT_NUMERO_BEN_DISPONIBLE, namedParameters,
					Integer.class);
			return disponibles;
		} catch (IncorrectResultSizeDataAccessException e) {
			return 0;
		}
	}

	public boolean otorgarBeneficios(Long codeSede, Long codeSubprograma,
			Long codeBeneficiario,
			List<Beneficiario_AtributoVO> lListaInsertar, String tercero,
			int i, String[] strArrIns, String costoBeneficio,
			String fechaBeneficio) {
		boolean retorno = true;

		boolean cantidad = checkBeneficio(codeSede, codeSubprograma);
		// boolean vigenciaSede = checkVigencia(codeSede, codeSubpro);
		boolean sw = false;
		String strCodeSede = codeSede + "";
		String strCodeSubpro = codeSubprograma + "";
		String strCodeBeneficiario = codeBeneficiario + "";

		if (cantidad) {
			int tamanoinsert = lListaInsertar.size();

			// proceso para insertar en la tabla beneficio otorgado
			String strArr[] = { strCodeSubpro, strCodeBeneficiario,
					strCodeSede, tercero, costoBeneficio, strArrIns[0],
					strArrIns[1], strArrIns[0], strArrIns[1] };

			// subProgramaDAO = new SubprogramaDAOImpl();

			int insertbienBeneOtorgado = subprogramaServiceImpl2
					.insertBeneficioOtorgado(strArr, i, fechaBeneficio);
			// fin del proceso

			if (tercero == null) {
				sw = true;
			} else {
				if (tercero.equals("")) {
					sw = true;
				}
			}

			// Proceso para actualizar la cantidad disponible
			if (sw) {
				updateBeneficioDisponible(codeSede, codeSubprograma);
			}
			// fin del proceso

			// proceso para calcular el codigo maximo en la tabla beneficio
			// otorgado
			String codMaxBenefOtor = subprogramaServiceImpl2
					.findCodMaxBenOtor();
			// fin del proceso

			for (int j = 0; j < tamanoinsert; j++) {
				Beneficiario_AtributoVO objBenAtri = (Beneficiario_AtributoVO) lListaInsertar
						.get(j);

				if (objBenAtri.getVariable().trim().equals("") == false) {
					if ((objBenAtri.getTipoatributo()).equals("R")) {
						int insertobeneficiarioatri = atributosServiceImpl
								.insertBeneficiarioAtri(
										objBenAtri.getVariable().trim(),
										objBenAtri.getTipodato(),
										new Long(objBenAtri.getCodigoatributo()),
										new Long(objBenAtri
												.getCodbeneficiario()), i,
										strArrIns);
					} else {
						int insertobeneficioatri = atributosServiceImpl
								.insertBeneficioAtri(
										objBenAtri.getVariable().trim(),
										objBenAtri.getTipodato(),
										new Long(objBenAtri.getCodigoatributo()),
										new Long(codMaxBenefOtor), i, strArrIns);
					}
				}
			}
		} else {
			return retorno = false;
		}
		return retorno;
	}

	public boolean otorgarBeneficios(Long codeSede, Long codeSubprograma,
			Long codeBeneficiario,
			List<Beneficiario_AtributoVO> lListaInsertar, String tercero,
			int i, String[] strArrIns, String costoBeneficio,
			String fechaBeneficio, String tipoBeneficio,
			String codeHechoVictimizante) {
		boolean retorno = true;

		boolean cantidad = checkBeneficio(codeSede, codeSubprograma);
		// boolean vigenciaSede = checkVigencia(codeSede, codeSubpro);
		boolean sw = false;
		String strCodeSede = codeSede + "";
		String strCodeSubpro = codeSubprograma + "";
		String strCodeBeneficiario = codeBeneficiario + "";

		if (cantidad)// && vigenciaSede)
		{

			int tamanoinsert = lListaInsertar.size();

			// proceso para insertar en la tabla beneficio otorgado
			String strArr[] = { strCodeSubpro, strCodeBeneficiario,
					strCodeSede, tercero, costoBeneficio, tipoBeneficio,
					strArrIns[0], strArrIns[1], strArrIns[0], strArrIns[1],
					codeHechoVictimizante };

			int insertbienBeneOtorgado = subprogramaServiceImpl2
					.insertBeneficioOtorgado(strArr, i, fechaBeneficio);
			// fin del proceso

			if (tercero == null) {
				sw = true;
			} else {
				if (tercero.equals("")) {
					sw = true;
				}
			}

			// Proceso para actualizar la cantidad disponible
			if (sw) {
				updateBeneficioDisponible(codeSede, codeSubprograma);
			}
			// fin del proceso

			// proceso para calcular el codigo maximo en la tabla beneficio
			// otorgado
			String CodMaxBenefOtor = subprogramaServiceImpl2
					.findCodMaxBenOtor();
			// fin del proceso

			for (int j = 0; j < tamanoinsert; j++) {
				Beneficiario_AtributoVO objBenAtri = (Beneficiario_AtributoVO) lListaInsertar
						.get(j);

				if (objBenAtri.getVariable().trim().equals("") == false) {
					if ((objBenAtri.getTipoatributo()).equals("R")) {
						int insertobeneficiarioatri = atributosServiceImpl
								.insertBeneficiarioAtri(
										objBenAtri.getVariable().trim(),
										objBenAtri.getTipodato(),
										new Long(objBenAtri.getCodigoatributo()),
										new Long(objBenAtri
												.getCodbeneficiario()), i,
										strArrIns);

					} else {
						int insertobeneficioatri = atributosServiceImpl
								.insertBeneficioAtri(
										objBenAtri.getVariable().trim(),
										objBenAtri.getTipodato(),
										new Long(objBenAtri.getCodigoatributo()),
										new Long(CodMaxBenefOtor), i, strArrIns);
					}
				}
			}
		} else {
			return retorno = false;
		}
		return retorno;
	}

	public boolean otorgarBeneficiosEmpresa(Long codeSede,
			Long codeSubprograma, Long codeEmpresa,
			List<Beneficiario_AtributoVO> lListaInsertar, String tercero,
			int i, String[] strArrIns, String costoBeneficio,
			String fechaBeneficio, String tipoBeneficio) {
		boolean retorno = true;

		boolean cantidad = checkBeneficio(codeSede, codeSubprograma);

		boolean sw = false;
		String strCodeSede = codeSede + "";
		String strCodeSubpro = codeSubprograma + "";
		String strCodeEmpresa = codeEmpresa + "";

		if (cantidad) {

			int tamanoinsert = lListaInsertar.size();

			// proceso para insertar en la tabla beneficio otorgado
			String strArr[] = { strCodeSubpro, strCodeEmpresa, strCodeSede,
					tercero, costoBeneficio, tipoBeneficio, strArrIns[0],
					strArrIns[1], strArrIns[0], strArrIns[1] };

			int insertbienBeneOtorgado = subprogramaServiceImpl2
					.insertBeneficioOtorgadoEmpresa(strArr, i, fechaBeneficio);
			// fin del proceso

			if (tercero == null) {
				sw = true;
			} else {
				if (tercero.equals("")) {
					sw = true;
				}
			}

			// Proceso para actualizar la cantidad disponible
			if (sw) {
				updateBeneficioDisponible(codeSede, codeSubprograma);
			}
			// fin del proceso

			// proceso para calcular el codigo maximo en la tabla beneficio
			// otorgado
			String CodMaxBenefOtor = subprogramaServiceImpl2
					.findCodMaxBenOtor();
			// fin del proceso

			for (int j = 0; j < tamanoinsert; j++) {
				Beneficiario_AtributoVO objBenAtri = (Beneficiario_AtributoVO) lListaInsertar
						.get(j);

				if (objBenAtri.getVariable().trim().equals("") == false) {
					System.err
							.println("[BeneficioDAO.OtorgarBeneficios]tipo atributo="
									+ objBenAtri.getTipoatributo());
					if ((objBenAtri.getTipoatributo()).equals("R")) {
						int insertobeneficiarioatri = atributosServiceImpl
								.insertBeneficiarioAtri(
										objBenAtri.getVariable().trim(),
										objBenAtri.getTipodato(),
										new Long(objBenAtri.getCodigoatributo()),
										new Long(objBenAtri
												.getCodbeneficiario()), i,
										strArrIns);

					} else {
						int insertobeneficioatri = atributosServiceImpl
								.insertBeneficioAtri(
										objBenAtri.getVariable().trim(),
										objBenAtri.getTipodato(),
										new Long(objBenAtri.getCodigoatributo()),
										new Long(CodMaxBenefOtor), i, strArrIns);
					}
				}
			}
		} else {
			return retorno = false;
		}
		return retorno;
	}

	public boolean updateBOT(Long codeSede, Long codeSubprograma,
			Long codeBeneficiario,
			List<Beneficiario_AtributoVO> lListaInsertar, String tercero,
			int i, String[] strArrIns, String costoBeneficio,
			String fechaBeneficio, Long codeBot, Long codeSedeOld,
			String tipoBot, Long codigoHechoVictimizante) {
		boolean retorno = true;
		boolean cantidad = false;

		cantidad = (codeSede.longValue() == codeSedeOld.longValue()) ? true
				: checkBeneficio(new Long(codeSede.longValue()),
						codeSubprograma);
		boolean sw = false;
		if (cantidad) {

			int tamanoinsert = lListaInsertar.size();

			// proceso para actualizar en la tabla beneficio otorgado
			String strArr[] = { codeSede.toString(), tercero, costoBeneficio,
					strArrIns[0], strArrIns[1] };

			int updated = subprogramaServiceImpl2.updateBeneficioOtorgado(
					strArr, i, fechaBeneficio, codeBot.toString(), tipoBot,
					codigoHechoVictimizante);
			// fin del proceso

			if (updated == 1) {
				if (tercero == null) {
					sw = true;
				} else {
					if (tercero.equals("")) {
						sw = true;
					}
				}

				// Proceso para actualizar la cantidad disponible
				if (sw && !codeSede.equals(codeSedeOld)) {
					// Para disminuir en uno el numero de beneficios
					// disponibles en la nueva sede
					updateBeneficioDisponible(codeSede, codeSubprograma);

					// Para aumentar en uno el numero de beneficios
					// disponibles en la nueva sede
					aumentarBeneficioDisponible(codeSedeOld, codeSubprograma);
				}
				// fin del proceso

				for (int j = 0; j < tamanoinsert; j++) {
					Beneficiario_AtributoVO objBenAtri = (Beneficiario_AtributoVO) lListaInsertar
							.get(j);
					// System.err.println("[BeneficioDAO.UpdateBOT]tipo atributo="
					// + objBenAtri.getTipoatributo());
					if ((objBenAtri.getTipoatributo()).equals("R")) {
						int updatedbeneficiarioatri = atributosServiceImpl
								.insertBeneficiarioAtri(
										objBenAtri.getVariable().trim(),
										objBenAtri.getTipodato(),
										new Long(objBenAtri.getCodigoatributo()),
										new Long(objBenAtri
												.getCodbeneficiario()), i,
										strArrIns);

					} else {
						int updatedbeneficioatri = atributosServiceImpl
								.updateBeneficioAtri(
										objBenAtri.getVariable().trim(),
										objBenAtri.getTipodato(),
										new Long(objBenAtri.getCodigoatributo()),
										codeBot, i, strArrIns);

					}
				}
			} else {
				return retorno = false;
			}
		} else {
			return retorno = false;
		}
		return retorno;
	}

	public String findSedeBOT(String codeBot) {
		Map<String, Object> namedParameters = new HashMap<String, Object>();

		String query = "SELECT CODSEDE FROM VCS_BENEFICIOS_OTORGADOS "
				+ " WHERE CODBOT = :CODBOT ";

		namedParameters.put("CODBOT", codeBot);
		System.out.println("findSedeBOT: " + query);
		System.out.println(codeBot);
		try {
			String codeSede = getNamedParameterJdbcTemplate().queryForObject(
					query, namedParameters, String.class);
			return codeSede;
		} catch (IncorrectResultSizeDataAccessException e) {
			return null;
		}
	}

	public Collection<BeneficioVO> findDetallesBeneficios(Long codeBeneficio,
			Long codeSubprograma) {
		Map<String, Object> namedParameters = new HashMap<String, Object>();

		String query = "SELECT * FROM VCS_BENEFICIOS_OTORGADOS "
				+ " WHERE CODBEN = :CODBEN AND CODSUBPROG = :CODSUBPROG ORDER BY CODBOT";

		namedParameters.put("CODBEN", codeBeneficio);
		namedParameters.put("CODSUBPROG", codeSubprograma);

		List<BeneficioVO> beneficios = new ArrayList<BeneficioVO>();

		List<Map<String, Object>> rows = getNamedParameterJdbcTemplate()
				.queryForList(query.toString(), namedParameters);
		int total = 0;
		for (Map<String, Object> row : rows) {
			BeneficioVO vo = new BeneficioVO();
			BigDecimal codeSubprog = (BigDecimal) row.get("CODSUBPROG");
			if (codeSubprog != null) {
				vo.setCode(codeSubprog.longValueExact());
			}
			vo.setNombre((String) row.get("NOMSUBPROG"));
			vo.setFecha((String) row.get("FECHA"));
			BigDecimal codeSede = (BigDecimal) row.get("CODSEDE");
			if (codeSede != null) {
				vo.setCodSede(codeSede.longValueExact());
			}
			vo.setNomSede((String) row.get("NOMSEDE"));
			BigDecimal codeBOT = (BigDecimal) row.get("CODBOT");
			if (codeBOT != null) {
				vo.setCodeBot(codeBOT.longValueExact());
			}
			BigDecimal valor = (BigDecimal) row.get("Valor");
			if (valor != null) {
				vo.setValor(valor.intValueExact());
				total += valor.intValueExact();
			}

			beneficios.add(vo);
		}
		if (beneficios != null && beneficios.size() > 0) {
			BeneficioVO beneficioVO = new BeneficioVO();
			beneficioVO.setCode(new Long("0"));
			beneficioVO.setNombre("TOTAL");
			beneficioVO.setFecha("");
			beneficioVO.setCodSede(new Long("0"));
			beneficioVO.setNomSede("");
			beneficioVO.setCodeBot(new Long("0"));
			beneficioVO.setValor(total);
			beneficios.add(beneficioVO);
		}
		return beneficios;
	}

	public boolean deleteBOT(String codeBOT) {
		Map<String, Object> namedParameters = new HashMap<String, Object>();

		String query = " SELECT SBPR_CODIGO, SEDE_CODIGO "
				+ " FROM TCS_BEN_BENEFICIO_OTORGADO WHERE CODIGO = :CODIGO ";
		long codeSede;
		long codeSub;
		int delete;

		namedParameters.put("CODIGO", codeBOT);
		SubprogramaSedeVO cods = getNamedParameterJdbcTemplate()
				.queryForObject(query, namedParameters,
						new RowMapper<SubprogramaSedeVO>() {
							public SubprogramaSedeVO mapRow(ResultSet rs,
									int rowNum) throws SQLException {
								SubprogramaSedeVO vo = new SubprogramaSedeVO();
								vo.setCodeSubprograma(rs.getLong("SBPR_CODIGO"));
								vo.setCodeSede(rs.getLong("SEDE_CODIGO"));
								return vo;
							}
						});
		codeSede = cods.getCodeSede();
		codeSub = cods.getCodeSubprograma();

		query = " DELETE FROM tcs_ben_beneficio_atributo "
				+ " WHERE BOT_CODIGO = :BOT_CODIGO ";

		// reusar
		namedParameters.clear();
		namedParameters.put("BOT_CODIGO", codeBOT);
		delete = getNamedParameterJdbcTemplate().update(query, namedParameters);

		query = " DELETE FROM tcs_ben_beneficio_otorgado "
				+ " WHERE codigo = :codigo ";

		// reusar
		namedParameters.clear();
		namedParameters.put("codigo", codeBOT);
		delete += getNamedParameterJdbcTemplate()
				.update(query, namedParameters);

		if (delete > 0) {
			query = "SELECT MAX(codigo) codigo FROM tcs_ben_subprograma_sede "
					+ " WHERE sbpr_codigo = :sbpr_codigo AND sede_codigo = :sede_codigo ";

			// reusar
			namedParameters.clear();
			namedParameters.put("sbpr_codigo", codeSub);
			namedParameters.put("sede_codigo", codeSede);
			try {
				long code = getNamedParameterJdbcTemplate().queryForObject(
						query, namedParameters, Long.class);

				query = "UPDATE  TCS_BEN_SUBPROGRAMA_SEDE "
						+ " SET NUMERO_BEN_DISPONIBLE = NUMERO_BEN_DISPONIBLE + 1 "
						+ " WHERE codigo = :codigo ";
				namedParameters.clear();
				namedParameters.put("codigo", code);
				int update = getNamedParameterJdbcTemplate().update(query,
						namedParameters);
				if (update > 0) {
					return true;
				} else {
					throw new DAOException("");
				}

			} catch (IncorrectResultSizeDataAccessException e) {
				throw new DAOException(e);
			}
		}
		// TODO:
		throw new DAOException("");
	}

	public boolean validarDeleteBOT(String groupUserName, String userName,
			Long codeBOT) {
		Map<String, Object> namedParameters = new HashMap<String, Object>();

		String query = "SELECT COUNT(1) cantidad "
				+ " FROM VCS_BENEFICIOS_OTORGADOS "
				+ " WHERE ('ADMINISTRADOR GENERAL' = :groupUserName "
				+ " OR 'SUPER USUARIO' = :groupUserName "
				+ " OR USUARIOCREA = :userName ) AND CODBOT = :codeBOT ";

		namedParameters.put("groupUserName", groupUserName);
		namedParameters.put("userName", userName);
		namedParameters.put("codeBOT", codeBOT);
		try {
			int cantidad = getNamedParameterJdbcTemplate().queryForObject(
					query, namedParameters, Integer.class);
			if (cantidad > 0) {
				return true;
			} else {
				return false;
			}
		} catch (IncorrectResultSizeDataAccessException e) {
			return false;
		}
	}

	public boolean validarEditBOT(String groupUserName, String userName,
			Long codeBOT) {
		Map<String, Object> namedParameters = new HashMap<String, Object>();

		String query = "SELECT COUNT(1) cantidad "
				+ " FROM VCS_BENEFICIOS_OTORGADOS"
				+ " WHERE ('ADMINISTRADOR GENERAL' = :groupUserName "
				+ " OR 'SUPER USUARIO' = :groupUserName "
				+ " OR USUARIOCREA = :userName ) AND CODBOT = :codeBOT ";

		namedParameters.put("groupUserName", groupUserName);
		namedParameters.put("userName", userName);
		namedParameters.put("codeBOT", codeBOT);

		try {
			int cantidad = getNamedParameterJdbcTemplate().queryForObject(
					query, namedParameters, Integer.class);
			if (cantidad > 0) {
				return true;
			} else {
				return false;
			}
		} catch (IncorrectResultSizeDataAccessException e) {
			return false;
		}
	}

	// TODO: TEST!
	public boolean renewBeneficio(Long codeSubpro, Long codeBeneficiario,
			Long codeOldSede, Long codeNewSede, String fechaOtorgamiento) {
		Map<String, Object> namedParameters = new HashMap<String, Object>();

		boolean retorno = true;
		if ((Object) codeSubpro != null && (Object) codeBeneficiario != null
				&& (Object) codeNewSede != null) {

			int iRegInsert = 0;
			if (!checkBeneficio(codeNewSede, codeSubpro)) {
				throw new DAOException("");
			}

			String query = " INSERT INTO TCS_BEN_BENEFICIO_OTORGADO "
					+ " (CODIGO, SBPR_CODIGO, BEN_CODIGO, "
					+ " SEDE_CODIGO, FECHA_BENEFICIO) "
					+ " VALUES (SCS_BEN_BOT.NextVal, :SBPR_CODIGO, :BEN_CODIGO, :SEDE_CODIGO, TO_CHAR(sysdate,'dd/mm/rrrr')) ";

			namedParameters.put("SBPR_CODIGO", codeSubpro);
			namedParameters.put("BEN_CODIGO", codeBeneficiario);
			namedParameters.put("SEDE_CODIGO", codeNewSede);

			iRegInsert = getNamedParameterJdbcTemplate().update(query,
					namedParameters);
			if (iRegInsert <= 0) {
				throw new DAOException("");
			}

			query = "SELECT SCS_BEN_BOT.currval codigo FROM dual ";
			Long codeBotNuevo = null;
			try {
				codeBotNuevo = getNamedParameterJdbcTemplate().queryForObject(
						query, namedParameters, Long.class);
			} catch (IncorrectResultSizeDataAccessException e) {
				throw new DAOException(e);
			}

			query = "SELECT codigo FROM TCS_BEN_SUBP_ATR_BENEFICIARIO "
					+ " WHERE SBPR_CODIGO = :SBPR_CODIGO "
					+ " AND TIPO_ATRIBUTO = 'B' ";

			namedParameters.clear();
			namedParameters.put("SBPR_CODIGO", codeSubpro);
			List<Long> codigos = getNamedParameterJdbcTemplate().query(query,
					namedParameters, new RowMapper<Long>() {

						public Long mapRow(ResultSet rs, int rowNum)
								throws SQLException {
							return rs.getLong("codigo");
						}
					});

			query = " SELECT codigo FROM TCS_BEN_BENEFICIO_OTORGADO "
					+ " WHERE SBPR_CODIGO = :SBPR_CODIGO AND BEN_CODIGO = :BEN_CODIGO "
					+ " AND SEDE_CODIGO = :SEDE_CODIGO "
					+ " AND FECHA_BENEFICIO = TO_DATE(:FECHA_BENEFICIO) ";

			//
			namedParameters.clear();
			namedParameters.put("SBPR_CODIGO", codeSubpro);
			namedParameters.put("BEN_CODIGO", codeBeneficiario);
			namedParameters.put("SEDE_CODIGO", codeOldSede);
			namedParameters.put("FECHA_BENEFICIO", fechaOtorgamiento);
			Long rst2 = null;
			try {
				rst2 = getNamedParameterJdbcTemplate().queryForObject(query,
						namedParameters, Long.class);
			} catch (IncorrectResultSizeDataAccessException e) {
				throw new DAOException(e);
			}

			for (Long rst : codigos) {
				if (!updateBeneficioAtributo(rst, codeBotNuevo, rst2)) {
					throw new DAOException("");
				}
			}

			query = "UPDATE TCS_BEN_BENEFICIO_OTORGADO SET campo_a1 = 'I' WHERE codigo = :codigo ";
			namedParameters.clear();
			namedParameters.put("codigo", rst2);

			int iReg = getNamedParameterJdbcTemplate().update(query,
					namedParameters);
			if (iReg <= 0) {
				throw new DAOException("");
			}
		}

		updateBeneficioDisponible(codeNewSede, codeSubpro);

		return retorno;
	}

	public Collection<UsuarioxSedeVO> findUsuarioxBeneficio(String idben) {
		Map<String, Object> namedParameters = new HashMap<String, Object>();

		String query = "SELECT PRG.NOMBRE PROGRAMA,SUB .NOMBRE SUBPROGRAMA,SEDE.NOMBRE, USU.NOMBRE USUARIO "
				+ " FROM TCS_BEN_PROGRAMA PRG, TCS_BEN_SUBPROGRAMA SUB, TCS_BEN_SEDE SEDE, TCS_BEN_SUBPROGRAMA_SEDE SUBSEDE, TCS_BEN_USUARIO_SEDE USUSEDE, PAOYER.TCS_USUARIO USU "
				+ " WHERE PRG.CODIGO = SUB. PRG_CODIGO AND SUB.CODIGO = SUBSEDE. SBPR_CODIGO AND SEDE.CODIGO = SUBSEDE. SEDE_CODIGO AND SUBSEDE.CODIGO = USUSEDE. SPSE_CODIGO AND USU.CODIGO = USUSEDE. USU_CODIGO "
				+ " AND SUB.CODIGO = :CODIGO ";

		namedParameters.put("CODIGO", idben);
		List<UsuarioxSedeVO> usuarios = getNamedParameterJdbcTemplate().query(
				query, namedParameters, new RowMapper<UsuarioxSedeVO>() {
					public UsuarioxSedeVO mapRow(ResultSet rs, int rowNum)
							throws SQLException {
						UsuarioxSedeVO vo = new UsuarioxSedeVO();
						vo.setNombreUsuario(rs.getString("USUARIO"));
						// usu.setCodeUsuario(new
						// Long(rs.getString("codeusu")));
						vo.setNombrePrograma(rs.getString("PROGRAMA"));
						vo.setNombreSubprograma(rs.getString("SUBPROGRAMA"));
						return vo;
					}
				});
		return usuarios;
	}

	public String findPrograma(String codeSubprograma) {
		Map<String, Object> namedParameters = new HashMap<String, Object>();

		String strSql = "SELECT PRG_CODIGO FROM TCS_BEN_SUBPROGRAMA "
				+ " WHERE CODIGO = :CODIGO ";

		namedParameters.put("CODIGO", codeSubprograma);
		return getNamedParameterJdbcTemplate().queryForObject(strSql,
				namedParameters, String.class);
	}

	private void updateBeneficioDisponible(Long codeSede, Long codeSubprograma)
			throws DAOException {
		Map<String, Object> namedParameters = new HashMap<String, Object>();

		String query = "";
		if ((Object) codeSede != null && (Object) codeSubprograma != null) {
			query = "SELECT MAX(codigo) codigo FROM tcs_ben_subprograma_sede "
					+ " WHERE sbpr_codigo = :sbpr_codigo AND sede_codigo = :sede_codigo ";

			namedParameters.put("sbpr_codigo", codeSubprograma);
			namedParameters.put("sede_codigo", codeSede);

			try {
				long codigo = getNamedParameterJdbcTemplate().queryForObject(
						query, namedParameters, Long.class);

				namedParameters.clear();
				query = "UPDATE  TCS_BEN_SUBPROGRAMA_SEDE "
						+ " SET NUMERO_BEN_DISPONIBLE = NUMERO_BEN_DISPONIBLE - 1 "
						+ " WHERE codigo = :codigo ";

				namedParameters.put("codigo", codigo);

				int iReg = getNamedParameterJdbcTemplate().update(query,
						namedParameters);
				if (iReg == 0) {
					throw new DAOException("");
				}
			} catch (IncorrectResultSizeDataAccessException e) {
				throw new DAOException(e);
			}
		}
	}

	private boolean checkBeneficio(Long codeSede, Long codeSubpro)
			throws DAOException {
		Map<String, Object> namedParameters = new HashMap<String, Object>();

		boolean retorno = false;
		if ((Object) codeSede == null || (Object) codeSubpro == null) {
			return retorno;
		}
		StringBuffer query = new StringBuffer(
				"SELECT NUMERO_BEN_DISPONIBLE "
						+ " FROM TCS_BEN_SUBPROGRAMA_SEDE WHERE SEDE_CODIGO = :SEDE_CODIGO AND SBPR_CODIGO = :SBPR_CODIGO ");

		namedParameters.put("SEDE_CODIGO", codeSede);
		namedParameters.put("SBPR_CODIGO", codeSubpro);

		try {
			int disponibles = getNamedParameterJdbcTemplate().queryForObject(
					query.toString(), namedParameters, Integer.class);
			if (disponibles > 0) {
				return true;
			}
		} catch (IncorrectResultSizeDataAccessException e) {
			return false;
		}
		return retorno;
	}

	private boolean updateBeneficioAtributo(Long codeAtributo,
			Long codeBotNuevo, Long codeBotViejo) throws DAOException {
		Map<String, Object> namedParameters = new HashMap<String, Object>();

		String query = "UPDATE TCS_BEN_BENEFICIO_ATRIBUTO SET bot_codigo = :BOT_CODIGO_NUEVO "
				+ " WHERE BOT_CODIGO = :BOT_CODIGO_VIEJO AND SAB_CODIGO = :SAB_CODIGO ";

		namedParameters.put("BOT_CODIGO_NUEVO", codeBotNuevo);
		namedParameters.put("BOT_CODIGO_VIEJO", codeBotViejo);
		namedParameters.put("SAB_CODIGO", codeAtributo);

		int iRegUpdate = getNamedParameterJdbcTemplate().update(query,
				namedParameters);
		if (iRegUpdate > 0) {
			return true;
		} else {
			return false;
		}
	}

	private void aumentarBeneficioDisponible(Long codeSede, Long codeSubpro)
			throws DAOException {
		Map<String, Object> namedParameters = new HashMap<String, Object>();

		String query = "";
		if ((Object) codeSede != null && (Object) codeSubpro != null) {
			query = "SELECT MAX(codigo) codigo FROM tcs_ben_subprograma_sede "
					+ " WHERE sbpr_codigo = :sbpr_codigo AND sede_codigo = :sede_codigo ";

			boolean found = false;
			Long codigo = null;

			namedParameters.put("sbpr_codigo", codeSubpro);
			namedParameters.put("sede_codigo", codeSede);

			try {
				codigo = getNamedParameterJdbcTemplate().queryForObject(query,
						namedParameters, Long.class);
				found = true;
			} catch (IncorrectResultSizeDataAccessException e) {
				throw new DAOException(e);
			}

			if (found) {
				namedParameters.clear();
				query = "UPDATE  TCS_BEN_SUBPROGRAMA_SEDE "
						+ " SET NUMERO_BEN_DISPONIBLE = NUMERO_BEN_DISPONIBLE + 1 "
						+ " WHERE codigo = :codigo ";

				namedParameters.put("codigo", codigo);
				getNamedParameterJdbcTemplate().update(query, namedParameters);
			}

		}
	}

	public String findCodigoSedeByCodigoSubprograma(Long codigoSubprograma) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public BeneficioOtorgadoVO findBOT(Long codeBOT) {
		Map<String, Object> namedParameters = new HashMap<String, Object>();

		String query = "SELECT CODIGO, SBPR_CODIGO, BEN_CODIGO, "
				+ " SEDE_CODIGO, trim(TERCERO) tercero, TO_CHAR(FECHA_BENEFICIO, 'dd/MM/yyyy') FECHA_BENEFICIO, "
				+ " TRIM(TIPO_BENEFICIO) tipo_beneficio, HECHO_VICTIMIZANTE "
				+ " FROM TCS_BEN_BENEFICIO_OTORGADO WHERE CODIGO = :CODIGO";

		namedParameters.put("CODIGO", codeBOT);

		try {
			BeneficioOtorgadoVO bot = getNamedParameterJdbcTemplate()
					.queryForObject(query, namedParameters,
							new RowMapper<BeneficioOtorgadoVO>() {

								@Override
								public BeneficioOtorgadoVO mapRow(ResultSet rs,
										int arg1) throws SQLException {
									BeneficioOtorgadoVO vo = new BeneficioOtorgadoVO();
									vo.setCodigo(rs.getLong("CODIGO"));
									vo.setSbprCodigo(rs.getLong("SBPR_CODIGO"));
									vo.setBenCodigo(rs.getLong("BEN_CODIGO"));
									vo.setSedeCodigo(rs.getLong("SEDE_CODIGO"));
									vo.setTercero(rs.getString("TERCERO"));
									vo.setFechaBeneficio(rs
											.getString("FECHA_BENEFICIO"));
									vo.setTipoBeneficio(rs
											.getString("TIPO_BENEFICIO"));
									vo.setHechoVictimizante(rs
											.getLong("HECHO_VICTIMIZANTE"));
									return vo;
								}
							});
			return bot;
		} catch (IncorrectResultSizeDataAccessException e) {
			return null;
		}
	}

}
